package com.ruicar.afs.cloud.finance.mq.receiver.basic.processor;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruicar.afs.cloud.common.modules.contract.enums.*;
import com.ruicar.afs.cloud.common.mq.finance.cancel.dto.RefundSuccessDto;
import com.ruicar.afs.cloud.common.mq.rabbit.listener.AfsMqBizProcessor;
import com.ruicar.afs.cloud.common.mq.rabbit.message.MqTransCode;
import com.ruicar.afs.cloud.common.util.EmptyUtils;
import com.ruicar.afs.cloud.finance.common.entity.*;
import com.ruicar.afs.cloud.finance.common.service.*;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.Calendar;

/**
 * <p>Description: </p>
 *
 * @author ZC.GUO
 * @version 1.0
 * @date create on 2020-07-30 19:59
 */
@AllArgsConstructor
@Slf4j
@Component
public class RefundSuccessProcessor implements AfsMqBizProcessor<RefundSuccessDto> {

    private final FinanceVirtualAccountService financeVirtualAccountService;

    private final FinanceCustUnusedFundsService financeCustUnusedFundsService;

    private final FinanceUnusedFundsHistoryService financeUnusedFundsHistoryService;

    private final FinanceTransLineService financeTransLineService;

    private final FinanceReceiptOperateService financeReceiptOperateService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean processMessage(RefundSuccessDto entity) throws Exception {
        return this.transData(entity);
    }

    @Override
    public MqTransCode getCode() {
        return MqTransCode.AFS_CONTRACT_BASIC_FINANCE_CONTRACT_REFUND_AGREE;
    }

    @Override
    public boolean reQueueOnFail() {
        return true;
    }

    private boolean transData(RefundSuccessDto entity)throws Exception{
        /**  客户虚拟账户表 by ZC.GUO  **/
        FinanceVirtualAccount virtualAccount = this.handleVirtualAccount(entity);
        /**  当前待分配款项表 by ZC.GUO  **/
        this.handleCustUnusedFunds(entity);
        /**  账户余额分配流水表 by ZC.GUO  **/
        this.handleUnusedFundsHistory(entity,virtualAccount);
        /**  业务操作记录表 by ZC.GUO  **/
        FinanceTransLine transLine = this.handleTransLine(entity);
        /**  来款操作记录表 退款操作没有明细 by ZC.GUO  **/
        FinanceReceiptOperate receiptOperate = this.handleReceiptOperate(entity,transLine);
        return true;
    }


    private FinanceReceiptOperate handleReceiptOperate(RefundSuccessDto entity,FinanceTransLine transLine){
        FinanceReceiptOperate receiptOperate = new FinanceReceiptOperate();
        if (!ReceiptSourceTypeEnum.transferAccounts.equals(entity.getSourceType())){
            receiptOperate.setTransId(transLine.getId());
            receiptOperate.setFundsType(entity.getSourceType());
            receiptOperate.setFundsId(entity.getReceiptId());
            receiptOperate.setTime(Calendar.getInstance().getTime());
            receiptOperate.setType(ReceiptOperateTypeEnums.refund);
            receiptOperate.setAmount(entity.getRefundAmt());
            financeReceiptOperateService.save(receiptOperate);
        }
        return receiptOperate;
    }

    private FinanceTransLine handleTransLine(RefundSuccessDto entity){
        FinanceTransLine transLine = new FinanceTransLine();
        transLine.setCustNo(entity.getCustNo());
        transLine.setOperateType(TransOpreateTypeEnums.refund);
        transLine.setOperator(entity.getOperator());
        transLine.setOperateTime(Calendar.getInstance().getTime());
        transLine.setOperateResult(ReturnCodeEnum.success);
        financeTransLineService.save(transLine);
        return transLine;
    }

    private void handleUnusedFundsHistory(RefundSuccessDto entity,FinanceVirtualAccount virtualAccount){
        /**  非对公结算类型的退款 by ZC.GUO  **/
        if (!ReceiptSourceTypeEnum.transferAccounts.equals(entity.getSourceType())){
            FinanceUnusedFundsHistory unusedFundsHistory = new FinanceUnusedFundsHistory();
            unusedFundsHistory.setAccountId(virtualAccount.getId());
            unusedFundsHistory.setContractNo(entity.getContractNo());
            unusedFundsHistory.setFundsType(FundLineEnum.returnFunds);
            unusedFundsHistory.setFundId(entity.getReceiptId());
            unusedFundsHistory.setAmount(entity.getRefundAmt());
            financeUnusedFundsHistoryService.save(unusedFundsHistory);
        }
    }

    private FinanceVirtualAccount handleVirtualAccount(RefundSuccessDto entity){
        FinanceVirtualAccount virtualAccount = financeVirtualAccountService.getOne(Wrappers.<FinanceVirtualAccount>query().lambda()
                .eq(FinanceVirtualAccount::getCustNo,entity.getCustNo())
        );
        if (EmptyUtils.isNotEmpty(virtualAccount)){
            /**  非对公结算类型的退款，已入账金额进行冲减 by ZC.GUO  **/
            if (!ReceiptSourceTypeEnum.transferAccounts.equals(entity.getSourceType())){
                virtualAccount.setTotalAmt(virtualAccount.getTotalAmt().subtract(entity.getRefundAmt()));
                virtualAccount.setUnUsedAmt(virtualAccount.getUnUsedAmt().subtract(entity.getRefundAmt()));
            }
            virtualAccount.setReturnAmt(virtualAccount.getReturnAmt().add(entity.getRefundAmt()));
            financeVirtualAccountService.updateById(virtualAccount);
        }
        return virtualAccount;
    }


    private void handleCustUnusedFunds(RefundSuccessDto entity){
        FinanceCustUnusedFunds custUnusedFunds = financeCustUnusedFundsService.getOne(Wrappers.<FinanceCustUnusedFunds>query().lambda()
            .eq(FinanceCustUnusedFunds::getFundId,entity.getReceiptId())
        );
        if (EmptyUtils.isNotEmpty(custUnusedFunds)){
            /**  非对公结算类型的退款，删除 by ZC.GUO  **/
            if (!ReceiptSourceTypeEnum.transferAccounts.equals(entity.getSourceType())){
                financeCustUnusedFundsService.removeById(custUnusedFunds.getId());
            }
        }
    }
}
